import { getLanguage } from '@knno/i18n';
import { Component, cls, type StyledProps } from '@knno/jsx';
import SVGAlignCenter from '@mdi/svg/svg/format-align-center.svg';
import SVGAlignLeft from '@mdi/svg/svg/format-align-left.svg';
import SVGAlignRight from '@mdi/svg/svg/format-align-right.svg';
import SVGBold from '@mdi/svg/svg/format-bold.svg';
import SVGFillColor from '@mdi/svg/svg/format-color-fill.svg';
import SVGTextColor from '@mdi/svg/svg/format-color-text.svg';
import SVGItalic from '@mdi/svg/svg/format-italic.svg';
import SVGTextSize from '@mdi/svg/svg/format-size.svg';
import SVGUnderline from '@mdi/svg/svg/format-underline.svg';
import SVGImg from '@mdi/svg/svg/image-outline.svg';
import SVGTable from '@mdi/svg/svg/table.svg';
import { DICT } from '../../dict/dict';
import { ToolbarButton } from '../button/button';
import { ColorPicker } from '../colorPicker/colorPicker';
import { PopMenu } from '../popMenu/popMenu';
import type { ToolbarData } from './inlineEditor';
import { editorToolbarStyle } from './toolbar.css';

function isBold(str: string): boolean {
	if (str === 'bold') return true;
	if (/^\d+$/.test(str)) {
		return parseInt(str) > 400;
	} else {
		return false;
	}
}

function isAlignLeft(str: string): boolean {
	return !/^(center|right)$/i.test(str);
}

function isAlignCenter(str: string): boolean {
	return str === 'center';
}

function isAlignRight(str: string): boolean {
	return str === 'right';
}

export type EditorToolbarProps = StyledProps<EditorToolbar> & {
	data?: ToolbarData;
	readOnly?: boolean;
};

export class EditorToolbar extends Component<EditorToolbarProps> {
	protected render(): Node {
		const data = this.props.data;
		const elems = (data?.activeElements ?? []).filter((item) => item instanceof HTMLElement);
		const isPTd =
			elems.length > 0 &&
			elems.filter((elem) => elem.nodeName === 'P' || elem.nodeName === 'TD').length ===
				elems.length;
		const isPTdDiv =
			elems.length > 0 &&
			elems.filter(
				(elem) => elem.nodeName === 'P' || elem.nodeName === 'TD' || elem.nodeName === 'DIV',
			).length === elems.length;
		let btnLeft: ToolbarButton;
		let btnCenter: ToolbarButton;
		let btnRight: ToolbarButton;
		const props = this.props;
		return (
			<div
				class={cls(this.props.class, editorToolbarStyle)}
				style={this.props.style}
				onMouseDown={(evt) => evt.preventDefault()}
			>
				<ToolbarButton
					ref={(b) => (btnRight = b)}
					icon={SVGTextSize}
					menu
					title={DICT.fontSize}
					disabled={!isPTdDiv || props.readOnly}
					onClick={function () {
						PopMenu.show(
							[
								{ text: DICT.extremelySmall, size: 0.6 },
								{ text: DICT.verySmall, size: 0.75 },
								{ text: DICT.small, size: 0.9 },
								{ text: DICT.normal, size: 1 },
								{ text: DICT.big, size: 1.4 },
								{ text: DICT.veryBig, size: 1.8 },
								{ text: DICT.extremelyBig, size: 2.2 },
							],
							{
								refer: this.el,
								width: /^zh(-.+)?$/.test(getLanguage()) ? '10em' : '13em',
								popupPosition: 'bottom-left',
							},
						).onSelect((item) => {
							elems.forEach((elem) => {
								elem.style.fontSize = item.size + 'em';
							});
							data?.editor?.emitChange();
						});
					}}
				/>
				<ToolbarButton
					ref={(b) => (btnRight = b)}
					icon={SVGTextColor}
					menu
					title={DICT.textColor}
					disabled={!isPTdDiv || props.readOnly}
					onClick={function () {
						ColorPicker.show({ refer: this.el, useAction: true }).onSelect((color) => {
							elems.forEach((elem) => {
								elem.style.color = color;
							});
							data?.editor?.emitChange();
						});
					}}
				/>
				<ToolbarButton
					ref={(b) => (btnRight = b)}
					icon={SVGFillColor}
					menu
					title={DICT.backColor}
					disabled={!isPTdDiv || props.readOnly}
					onClick={function () {
						ColorPicker.show({ refer: this.el, useAction: true }).onSelect((color) => {
							elems.forEach((elem) => {
								elem.style.backgroundColor = color;
							});
							data?.editor?.emitChange();
						});
					}}
				/>
				<span />
				<ToolbarButton
					ref={(b) => (btnLeft = b)}
					title={DICT.alignLeft}
					icon={SVGAlignLeft}
					checkable
					checked={isPTdDiv && isAlignLeft(window.getComputedStyle(elems[0]).textAlign)}
					disabled={!isPTdDiv || props.readOnly}
					onClick={function () {
						this.setChecked(true);
						btnRight.setChecked(false);
						btnCenter.setChecked(false);
						elems.forEach((elem) => {
							elem.style.textAlign = 'unset';
							elem.style.textIndent = '';
						});
						data?.editor?.emitChange();
					}}
				/>
				<ToolbarButton
					ref={(b) => (btnCenter = b)}
					title={DICT.alignCenter}
					icon={SVGAlignCenter}
					checked={isPTdDiv && isAlignCenter(window.getComputedStyle(elems[0]).textAlign)}
					disabled={!isPTdDiv || props.readOnly}
					onClick={function () {
						this.setChecked(true);
						btnLeft.setChecked(false);
						btnRight.setChecked(false);
						elems.forEach((elem) => {
							elem.style.textAlign = 'center';
							elem.style.textIndent = '0';
						});
						data?.editor?.emitChange();
					}}
				/>
				<ToolbarButton
					ref={(b) => (btnRight = b)}
					title={DICT.alignRight}
					icon={SVGAlignRight}
					checked={isPTdDiv && isAlignRight(window.getComputedStyle(elems[0]).textAlign)}
					disabled={!isPTdDiv || props.readOnly}
					onClick={function () {
						this.setChecked(true);
						btnLeft.setChecked(false);
						btnCenter.setChecked(false);
						elems.forEach((elem) => {
							elem.style.textAlign = 'right';
							elem.style.textIndent = '0';
						});
						data?.editor?.emitChange();
					}}
				/>
				<span />
				<ToolbarButton
					title={DICT.textBold}
					icon={SVGBold}
					checked={isPTd && isBold(window.getComputedStyle(elems[0]).fontWeight)}
					disabled={!isPTd || props.readOnly}
					onClick={function () {
						elems.forEach((elem) => {
							elem.style.fontWeight = this.checked ? 'bold' : '';
						});
						data?.editor?.emitChange();
					}}
				/>
				<ToolbarButton
					title={DICT.textItalic}
					icon={SVGItalic}
					checked={isPTd && window.getComputedStyle(elems[0]).fontStyle === 'italic'}
					disabled={!isPTd || props.readOnly}
					onClick={function () {
						elems.forEach((elem) => {
							elem.style.fontStyle = this.checked ? 'italic' : '';
						});
						data?.editor?.emitChange();
					}}
				/>
				<ToolbarButton
					title={DICT.textUnderline}
					icon={SVGUnderline}
					checked={isPTd && /underline/.test(window.getComputedStyle(elems[0]).textDecoration)}
					disabled={!isPTd || props.readOnly}
					onClick={function () {
						elems.forEach((elem) => {
							elem.style.textDecoration = this.checked ? 'underline' : '';
						});
						data?.editor?.emitChange();
					}}
				/>
				<span />
				<ToolbarButton
					icon={SVGTable}
					title={DICT.insertTable}
					disabled={elems.length !== 1 || elems[0].nodeName !== 'P' || props.readOnly}
					onClick={() => data?.editor?.insertTable()}
				/>
				<ToolbarButton
					icon={SVGImg}
					title={DICT.insertImage}
					disabled={elems.length !== 1 || elems[0].nodeName !== 'P' || props.readOnly}
					onClick={() => data?.editor?.insertImage()}
				/>
				<div style={{ flex: 1 }}></div>
			</div>
		);
	}

	setData(data: ToolbarData | undefined): this {
		this.props.data = data;
		this.update();
		return this;
	}

	get readOnly(): boolean {
		return this.props.readOnly ?? false;
	}
	setReadOnly(value: boolean): this {
		this.props.readOnly = value;
		this.update();
		return this;
	}
}
